package TXPathFinder;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import javax.media.j3d.Appearance;
import javax.media.j3d.Material;
import javax.media.j3d.Shape3D;
import javax.vecmath.Color3f;

/**
*       \class	CurrentPath
*	\brief	Gere tout l'affichage en temps réel de la map cognitive d'un avatar (chemin + vision + déstination)
**/
public class CurrentPath
{

    private Appearance highlightAppearanceDeBase;
    private Appearance highlightAppearancePath;
    private Appearance highlightAppearanceSight;
    private Appearance highlightAppearanceRed;
    private Hashtable<String,Shape3D> tableShapeSight;
    private ArrayList<String> listPath;
    private String gotoShape;
    private int avatarCurrentPathAndSight;

    /**
    *	\brief	Constructeur
    **/
    public CurrentPath() {
        tableShapeSight = null;
        listPath = null;
        gotoShape = null;
        avatarCurrentPathAndSight = -1;

        //définit les couleurs du chemin et de la vision
        highlightAppearanceDeBase=new Appearance();
        Material mat = new Material();
        mat.setDiffuseColor(0.9f,0.9f,0.9f,1.0f);
        highlightAppearanceDeBase.setMaterial (mat);

        Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
        Color3f red = new Color3f(0.8f, 0.0f, 0.0f);
        Color3f highlightColorPath = new Color3f(0.0f, 0.0f, 0.0f);
        highlightAppearancePath = new Appearance();
        highlightAppearancePath.setMaterial(new Material(highlightColorPath, red,
            highlightColorPath, white, 250.0f));

        Color3f yellow = new Color3f(0.5f, 0.5f, 0.0f);
        Color3f highlightColorSight = new Color3f(0.0f, 0.0f, 0.0f);
        highlightAppearanceSight = new Appearance();
        highlightAppearanceSight.setMaterial(new Material(highlightColorSight, yellow,
            highlightColorPath, white, 200.0f));

        Color3f redd = new Color3f(1.0f, 0.0f, 0.0f);
        highlightAppearanceRed = new Appearance();
        highlightAppearanceRed.setMaterial(new Material(highlightColorPath, redd,
        highlightColorPath, white, 250.0f));
    }

    /**
    *	\brief	méthode apellé quand l'avatar est séléctionné, cette méthode color dans le viewer3D la map cognitive de l'avatar
    **/
    public void selectAvatar(int idAvatar)
    {
        if( avatarCurrentPathAndSight != idAvatar )
        {
            avatarCurrentPathAndSight = idAvatar;
            DataModel.getInstance().setAvatarCurrent(idAvatar);
            tableShapeSight = DataModel.getInstance().getAvatar(idAvatar).getShapeSight();
            listPath = DataModel.getInstance().getAvatar(idAvatar).getPath();
            gotoShape = DataModel.getInstance().getAvatar(idAvatar).getGotoShape();

            //met la bonne couleur au shape
            //sight :
            Iterator itValue = tableShapeSight.values().iterator();
            while(itValue.hasNext()){
                Shape3D value = (Shape3D)itValue.next();
                value.setAppearance(highlightAppearanceSight);
            }
            //listPath :
            int size = listPath.size();
            for( int i = 0 ; i < size ; i++ )
            {
                (tableShapeSight.get(listPath.get(i))).setAppearance(highlightAppearancePath);
            }

            //goto :
            if( gotoShape != null )
                (tableShapeSight.get(gotoShape)).setAppearance(highlightAppearanceRed);
        }
    }

    /**
    *	\brief	Color le bloc spécifié en tant que chemin
     *  \param key L'identifiant du bloc de la carte à colorer
    **/
    public void addShapeToPath(String key)
    {
        if( (tableShapeSight != null) && (listPath != null) )
        {
            Shape3D shape = DataModel.getInstance().getFromShapeTable(key);
            shape.setAppearance(highlightAppearancePath);
            if( !isInCurrentSight(key) && ( !(key.equals(gotoShape)) ) )
                tableShapeSight.put(key,shape);
            listPath.add(key);
        }
    }

    /**
    *	\brief	Color le bloc spécifié en tant que vision
     *  \param key L'identifiant du bloc de la carte à colorer
    **/
    public void addShapeToSight(String key)
    {
        Shape3D shape = DataModel.getInstance().getFromShapeTable(key);
        shape.setAppearance(highlightAppearanceSight);
        tableShapeSight.put(key,shape);
    }

    /**
    *	\brief	Ajout de ghost sur la carte (un ghost est un avatar immobile rencontré par l'avatar selectionné)
     *  \param x Position x du ghost à ajouter
     *  \param y Position y du ghost à ajouter
    **/
    public void addGhost(int x, int y)
    {
        DataModel.getInstance().addGhost(x,y);
    }

    /**
    *	\brief	Color la destination de l'avatar
     *  \param keyGoto L'identifiant de la destination de l'avatar
    **/
    void addTarget(String keyGoto) {
        gotoShape = keyGoto;
        if( tableShapeSight != null )
        {
            Shape3D shape = DataModel.getInstance().getFromShapeTable(keyGoto);
            if( shape != null )
            {
                shape.setAppearance(highlightAppearanceRed);
                if( !isInCurrentSight(keyGoto) )
                    tableShapeSight.put(keyGoto,shape);
            }
        }
    }

    /**
    *	\brief	Test si un bloc à déjà été ajouté au chemin
     *  \param key L'identifiant du bloc
     *  \return True si l'identifiant du bloc est déjà ajouté au chemin
    **/
    public boolean isInCurrentPath(String key)
    {
        return listPath.contains(key);
    }

    /**
    *	\brief	Test si un bloc à déjà été ajouté a la vision
     *  \param key L'identifiant du bloc
     *  \return True si l'identifiant du bloc est déjà ajouté à la vision
    **/
    public boolean isInCurrentSight(String key)
    {
        if( tableShapeSight != null )
            return tableShapeSight.containsKey(key);
        return true;
    }

    /**
    *	\brief	Efface toute la map cognitive (remet la couleur d'origine pour chaque bloc)
    **/
    public void resetPath()
    {
        if( tableShapeSight != null )
        {
            avatarCurrentPathAndSight = -1;
            Iterator itValue = tableShapeSight.values().iterator();
            while(itValue.hasNext()){
                Shape3D value = (Shape3D)itValue.next();
                value.setAppearance(highlightAppearanceDeBase);
            }
            
            tableShapeSight = null;
            listPath = null;
            gotoShape = null;
            DataModel.getInstance().setAvatarCurrent(-1);

            //detruit les ghosts
            DataModel.getInstance().deleteAllGhost();
        }
    }

}
